package org.timeismoney.payment.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.timeismoney.payment.dao.ItemStuDetailDao;
import org.timeismoney.payment.exception.BizException;
import org.timeismoney.payment.model.ItemPaymentDetail;
import org.timeismoney.payment.model.ItemStuDetail;
import org.timeismoney.payment.model.ItemUnitDetail;
import org.timeismoney.payment.model.Student;
import org.timeismoney.payment.model.Unit;
import org.timeismoney.payment.service.ItemStuDetailService;
import org.timeismoney.payment.service.ItemUnitDetailService;
import org.timeismoney.payment.service.PaymentRecordService;
import org.timeismoney.payment.service.StudentService;

public class ItemStuDetailServiceImpl extends
		BaseServiceImpl<ItemStuDetail, Integer> implements ItemStuDetailService {

	private StudentService studentService;
	private ItemUnitDetailService unitDetailService;
	private PaymentRecordService paymentRecordService;

	public void setPaymentRecordService(PaymentRecordService paymentRecordService) {
		this.paymentRecordService = paymentRecordService;
	}

	public void setUnitDetailService(ItemUnitDetailService unitDetailService) {
		this.unitDetailService = unitDetailService;
	}

	public void setStudentService(StudentService studentService) {
		this.studentService = studentService;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public List<ItemPaymentDetail> findItemPaymentByStu(String stuNo,
			int schoolYearNo) {
		
		Student stu = studentService.get(stuNo);
		Unit unit = stu.getUnit();
		List<ItemPaymentDetail> unitItems = new ArrayList<ItemPaymentDetail>();
		findItemPaymentFromParentUnit(schoolYearNo,unit,unitItems);
		List stuItems = findDetailByYearAndStu(stuNo,schoolYearNo);
		for (ItemPaymentDetail itemPaymentDetail : unitItems) {
			if(!stuItems.contains(itemPaymentDetail)){
				stuItems.add(itemPaymentDetail);
			}
		}
		return stuItems;
	}
	
	public List<ItemStuDetail> findDetailByYearAndStu(String stuNo,int schoolYearNo){
		return getDao().find("from ItemPaymentDetail ipd left join fetch ipd.item where ipd.student.stuNo=? and ipd.schoolYear.schoolYearNo=?", stuNo,schoolYearNo);
	}

	private void findItemPaymentFromParentUnit(int schoolYearNo, Unit unit,
			List<ItemPaymentDetail> unitItems) {
		if (unit!=null) {
			List<ItemUnitDetail> temp = unitDetailService
					.findDetailByYearAndUnit(schoolYearNo, unit.getUnitNo());
			if (temp != null) {
				for (ItemUnitDetail itemUnitDetail : temp) {
					if (!unitItems.contains(itemUnitDetail)) {
						unitItems.add(itemUnitDetail);
					}
				}
				Unit parentUnit = unit.getParentUnit();
				findItemPaymentFromParentUnit(schoolYearNo, parentUnit,
						unitItems);
			}
		}
	}
	
	public void findIsExistingPaymentRecordByOverwritedItem(int schoolYearNo, Unit unit,ItemPaymentDetail detail){
		ItemUnitDetail overwritedItem = findFirstOverwritedItem(schoolYearNo,unit,detail);
		if(overwritedItem!=null){
			int count = paymentRecordService.findPaymentRecordByItemPaymentDetail(overwritedItem).size();
			if(count>0)
				throw new BizException(overwritedItem.getUnit().getUnitName()+"=>"+overwritedItem.getItem().getItemName()+"在学年"+overwritedItem.getSchoolYear().getSchoolYearName()+"存在已支付记录，无法覆盖！");
		}
	}

	private ItemUnitDetail findFirstOverwritedItem(int schoolYearNo, Unit unit,
			ItemPaymentDetail detail) {
		if (unit != null) {
			List<ItemUnitDetail> temp = unitDetailService
					.findDetailByYearAndUnit(schoolYearNo, unit.getUnitNo());
			if (temp != null) {
				for (ItemUnitDetail itemUnitDetail : temp) {
					if (itemUnitDetail.equals(detail)) {
						return itemUnitDetail;
					}
				}
				Unit parentUnit = unit.getParentUnit();
				return findFirstOverwritedItem(schoolYearNo, parentUnit, detail);
			}
		}
		return null;
	}

	@Override
	public void delete(ItemStuDetail e) {
		paymentRecordService.deleteByItemPaymentNo(e.getItemPaymentNo());
		super.delete(e);
	}

	public void deleteByStuNo(String stuNo) {
		((ItemStuDetailDao)getDao()).deleteByStuNo(stuNo);
	}

	public void deleteAllBySchoolYearNo(Integer schoolYearNo) {
		((ItemStuDetailDao)getDao()).deleteAllBySchoolYearNo(schoolYearNo);
	}

	public void deleteAllByItemNo(Integer itemNo) {
		((ItemStuDetailDao)getDao()).deleteAllByItemNo(itemNo);
	}

}
